﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////


#pragma once
#include "GnufInputControl.h"
#include "GnufInfo.h"
#include "GnufBaseUtils.h"

namespace gnuf {
    class Info;
    class MatrixButtonControl;

    class GNUF_BASE_EXPORT IMatrixButtonControlHandler
        : public IInputControlHandler
    {
        DEFINE_CAST_DERIVED(gnuf::IMatrixButtonControlHandler, gnuf::IInputControlHandler)
    public:
        virtual void onMatrixButtonClickedAt(Point p) = 0;
    };

    class GNUF_BASE_EXPORT MatrixButtonControlAdaptation
        : public InputControlAdaptation
    {
    protected:
        MatrixButtonControlAdaptation();
        virtual ~MatrixButtonControlAdaptation();

        // Inherits from InputControlAdaptation...
        virtual void onVisibilityChanged(bool) override {}
        virtual void onSelectionChanged(bool) override {}
    public:
        MatrixButtonControl* matrixButtonControl() const;

        virtual void onMatrixButtonClickedAt(Point p) {}
        virtual void setSelectedButton(Point p) {}
        virtual void addButtonAt(Point p) {}
        virtual void removeButtonAt(Point p) {}
        virtual void disableButtonAt(Point p) {}
        virtual void enableButtonAt(Point p) {}
        virtual void assignInfos(const std::map<Point, Info>&) {} 
    };

    class GNUF_BASE_EXPORT MatrixButtonControl final
        : public InputControl
    {
        CANNOT_COPY_OR_ASSIGN(MatrixButtonControl)
    public:
        static const EItemType Type;
        MatrixButtonControl(
            IMatrixButtonControlHandler*,
            EMatrixSize size,
            gcmp::OwnerPtr<Info>&& info);
        virtual ~MatrixButtonControl();

        IMatrixButtonControlHandler* matrixButtonControlHandler() const;

        const std::map<gnuf::Point, Info>& buttonInfos() const { return m_buttonInfos; }

        /// \brief 为矩阵按钮赋予info信息
        /// \details 矩阵按钮会提供一套默认的Info信息，使用图标来表示方位，如果不满足使用需求，可以自定义。
        /// \param buttonInfos 欲赋予矩阵按钮的信息，每个位置对应的Info，包括ToolTip和按钮图标。
        void assignInfos(const std::map<Point, Info>& buttonInfos, const MatrixButtonControlAdaptation* trigger = nullptr);

        EMatrixSize matrixSize() const { return m_size; }

        void setSelectedButton(Point p, const MatrixButtonControlAdaptation* trigger = nullptr);
        Point selectedButton() const { return m_selectedButton; }

        void addButtonAt(Point p, const MatrixButtonControlAdaptation* trigger = nullptr);

        void removeButtonAt(Point p, const MatrixButtonControlAdaptation* trigger = nullptr);

        void disableButtonAt(Point p, const MatrixButtonControlAdaptation* trigger = nullptr);

        void enableButtonAt(Point p, const MatrixButtonControlAdaptation* trigger = nullptr);

        inline const Info* info() const { return m_info.get(); }

        const std::set<Point>& voidPosition() const { return m_voidPosition; }
        const std::set<Point>& disabledPosition() const { return m_disabledPosition; }
    private:
        std::map<gnuf::Point, Info> m_buttonInfos;
        gcmp::OwnerPtr<Info> m_info;
        Point m_selectedButton{-1, -1};
        const EMatrixSize m_size = EMatrixSize::e2x2;

        std::set<Point> m_voidPosition;
        std::set<Point> m_disabledPosition;
    };
}
